package com.cm.etax.tianjin;

import com.cm.etax.BaseEtax;
import com.cm.etax.BaseFunction;
import com.cm.etax.FunctionResult;
import com.cm.etax.exceptions.EtaxException;
import com.cm.etax.sms.SmsBiz;
import com.cm.etax.tianjin.bean.SysApiResponse;
import com.cm.kits.RandomKits;
import com.cm.rpa.beans.Point;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;

/**
 * 电子税务局身份认证处理方法
 *
 * @author LWang 2023.01.29
 * @since 1.0.0
 */
@Slf4j
public class IdentityAuthenticationFunction extends BaseFunction {

    public IdentityAuthenticationFunction(BaseEtax etax) {
        super(etax);
    }

    /**
     * 验证是否需要进行身份验证
     *
     * @return true 需要身份验证，false 不需要身份验证
     */
    public boolean needIdentityAuthentication() {
        try {
            rpa().findElementWithInnerText("身份验证", By.id("dialog1title"), WAIT_TIME / 2);
            return true;
        } catch (NoSuchElementException e) {
            return false;
        }
    }

    /**
     * 短信超限消息
     */
    private static final String LIMIT_MESSAGE = "短信发送次数超限！";

    public FunctionResult<Object> identityAuthentication() {
        var currentUrl = rpa().url();
        try {
            var sessionUser = etax().function(SessionFunction.class).getSessionUser(false);
            var targetUrl = rpa().findElement(By.id("ecrzkxDxId")).getAttribute("src");
            // 因为跨域了，所以要将身份识别的 iframe 提升到顶级窗口
            rpa().visit(targetUrl);
            // 先进行滑动验证
            var dragHandler = rpa().findElement(By.cssSelector("div.drag > div.handler"), WAIT_TIME);
            rpa().moveTo(dragHandler);
            var drag = rpa().findElement(By.cssSelector("div.drag"));
            var handlerRect = rpa().sumElementRectangle(drag);
            rpa().dragTo(
                    new Point(
                            RandomKits.nextDouble(handlerRect.rightTop().x(), handlerRect.rightTop().x() + MOUSE_OFFSET),
                            RandomKits.nextDouble(handlerRect.rightTop().y() - MOUSE_OFFSET, handlerRect.rightBottom().y()) + MOUSE_OFFSET
                    )
            );
            var code = SmsBiz.waitSmsCode(sessionUser.sjh(), SmsBiz.SmsTaskType.ETAX_TIANJIN, () -> {
                rpa().newHar();
                rpa().findElementWithInnerText("获取验证码", By.cssSelector("button.el-button"), WAIT_TIME).click();
                var response = rpa().jsonListen("auth/oauth2/sendSmsByToke", SysApiResponse.class);
                if (!response.success()) {
                    if (response.msg().contains(LIMIT_MESSAGE)) {
                        throw new EtaxException(response.msg());
                    }
                }
            });
            rpa().sendKey(By.cssSelector("input.el-input__inner[placeholder=\"请输入短信验证码\"]"), code, false, WAIT_TIME);
            rpa().newHar();
            rpa().findElementWithInnerText("确定", By.cssSelector("button.el-button"), WAIT_TIME).click();
            var response = rpa().jsonListen("auth/oauth2/verifySmsCode", SysApiResponse.class);
            if (!response.success()) {
                throw new EtaxException(response.msg());
            }
            return new FunctionResult<>(true, "身份认证成功。", null);
        } catch (Exception e) {
            return handleException(e, "身份认证失败，");
        } finally {
            rpa().visit(currentUrl);
        }
    }
}
